import axios from 'axios'
import qs from 'qs'
import store from '@/store'
import { checkStatus } from './checkStatus'
import { ContentTypeEnum, RequestEnum } from '@/enums/httpEnum'

const axiosInstance = axios.create({
  baseURL: process.env.VUE_APP_API,
  withCredentials: true,
  timeout: 60 * 1000
})

/**
 * 请求前的拦截器
 */
axiosInstance.interceptors.request.use(
  (config) => {
    const { token } = store.getters

    if (token && token !== 'undefined' && token !== '') {
      // 将 token 写入 request header
      config.headers['token'] = token
    }
    return config
  },
  (error) => {
    return Promise.reject(error)
  }
)

/**
 * 请求前的拦截器
 * 统一处理请求异常
 * response.status = 200 且 response.data.code = 200
 */
axiosInstance.interceptors.response.use(
  (response) => {
    if (
      response.data &&
      typeof response.data === 'object' &&
      response.data.code &&
      response.data.code !== '200' &&
      response.data.code !== 200 &&
      response.data.code !== 2000
    ) {
      checkStatus(response.data.code, { ...response.config, errMsg: response.data?.message ?? '' })
      return Promise.reject(response)
    }
    return response
  },
  (error) => {
    const response = error.response || {}

    checkStatus(response.status, response.config)
    return Promise.reject(response)
  }
)

/**
 * deployUse 添加公共参数, 处理请求接口前的参数
 * @param   {object}  data     请求参数
 * @param   {any}     headers  headers类型
 */
function deployUse(data, headers) {
  if (headers['Content-Type'] === ContentTypeEnum.FORM_URLENCODED) {
    return qs.stringify(data)
  } else {
    return data
  }
}

/**
 * request
 * @param   {CreateAxiosOptions}  config   接口配置
 * @param   {any<any>}            data     参数
 */
const request = function (config, data) {
  // 设置默认headers
  const headers = {
    'Content-Type': ContentTypeEnum.JSON
  }
  // http配置
  const httpDefaultOpts = {
    ...config,
    headers: Object.assign(headers, config.headers)
  }

  // 处理get请求
  if (config.method.toUpperCase() === RequestEnum.GET) {
    httpDefaultOpts.params = deployUse(data, httpDefaultOpts.headers)
  } else {
    httpDefaultOpts.data = deployUse(data, httpDefaultOpts.headers)
  }

  // return new Promise
  return new Promise((resolve, reject) => {
    axiosInstance
      .request(httpDefaultOpts)
      .then((res) => {
        resolve(res)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

export { request }
export default request
